<template>
  <div class="tutorial">
    <h2>🛠️ 自定义过渡动画教程（CSS + JS 钩子）</h2>
    <p>自定义过渡不仅可以用 CSS，还能通过 JS 钩子实现精细控制。</p>

    <div class="controls">
      <button class="btn" @click="show = !show">{{ show ? '隐藏' : '显示' }}示例</button>
    </div>

    <transition name="custom" @before-enter="beforeEnter" @enter="enter" @leave="leave">
      <div v-if="show" class="demo-box">自定义示例区域</div>
    </transition>

    <h3>JS 钩子说明</h3>
    <pre class="code"><code>&lt;transition @before-enter=&quot;beforeEnter&quot; @enter=&quot;enter&quot; @leave=&quot;leave&quot;&gt;
// beforeEnter: 初始样式
// enter: 使用 requestAnimationFrame 逐步更新到目标样式
// leave: 反向动画并在结束时调用 done()
</code></pre>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const show = ref(true)

function beforeEnter(el) {
  el.style.opacity = 0
  el.style.transform = 'translateY(-8px)'
}

function enter(el, done) {
  const start = performance.now()
  const duration = 300
  function step(now) {
    const t = Math.min((now - start) / duration, 1)
    el.style.opacity = String(t)
    el.style.transform = `translateY(${(-8 + 8 * t).toFixed(2)}px)`
    if (t < 1) requestAnimationFrame(step)
    else done()
  }
  requestAnimationFrame(step)
}

function leave(el, done) {
  const start = performance.now()
  const duration = 250
  function step(now) {
    const t = Math.min((now - start) / duration, 1)
    el.style.opacity = String(1 - t)
    el.style.transform = `translateY(${(0 + -8 * t).toFixed(2)}px)`
    if (t < 1) requestAnimationFrame(step)
    else done()
  }
  requestAnimationFrame(step)
}
</script>

<style scoped>
.tutorial { padding: 20px; }
.controls { display:flex; gap:8px; }
.btn { padding:8px 12px; background:#3b82f6; color:#fff; border:none; border-radius:6px; cursor:pointer; }
.btn:hover { background:#2563eb; }
.demo-box { margin-top:12px; padding:20px; border-radius:12px; background:#eff6ff; border:1px solid #bfdbfe; }

/* 可选的 CSS 兜底样式（当 JS 钩子未触发时仍有过渡） */
.custom-enter-active, .custom-leave-active { transition: all .25s ease; }
.custom-enter-from, .custom-leave-to { opacity: 0; transform: translateY(-8px); }
.custom-enter-to, .custom-leave-from { opacity: 1; transform: translateY(0); }

.code { background: #1e1e1e; color: #d4d4d4; padding: 12px; border-radius: 8px; overflow:auto; margin-top: 16px; }
</style>